/*
 *  NFCSigning - Open source library for signing/validation of NDEF messages
 *  Copyright (C) 2009-2010 The NFCSigning Team
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 *
 */
package sampleappa;

import com.ericsson.nfc.signing.MessageToSign;
import com.ericsson.nfc.signing.algorithm.DSASigner;
import com.ericsson.nfc.signing.algorithm.ECDSASigner;
import com.ericsson.nfc.signing.algorithm.PrivateKey;
import com.ericsson.nfc.signing.algorithm.RSASSAPKCS1v15Signer;
import com.ericsson.nfc.signing.algorithm.RSASSAPSSSigner;
import com.ericsson.nfc.signing.Signature;
import com.ericsson.nfc.signing.SignedMessage;
import com.ericsson.nfc.signing.algorithm.SignatureException;
import com.ericsson.nfc.signing.algorithm.Signer;
import com.ericsson.nfc.signing.MessageValidator;
import com.ericsson.nfc.signing.algorithm.WrongPrivateKeyAlgorithm;
import com.ericsson.nfc.signing.certificate.Certificate;
import com.ericsson.nfc.signing.certificate.X509Certificate;
import com.ericsson.nfc.signing.certificate.X509CertificateChain;
import com.ericsson.nfc.signing.record.CertificateBytes;
import com.ericsson.nfc.signing.record.CertificateField;
import com.ericsson.nfc.signing.record.URIRecord;
import java.io.IOException;
import javax.microedition.io.Connector;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import org.bouncycastle.crypto.DataLengthException;
import org.bouncycastle.util.encoders.Base64;

//#ifdef MyJSR257
//# import my.javax.microedition.contactless.DiscoveryManager;
//# import my.javax.microedition.contactless.TargetListener;
//# import my.javax.microedition.contactless.TargetProperties;
//# import my.javax.microedition.contactless.TargetType;
//# import my.javax.microedition.contactless.ndef.NDEFMessage;
//# import my.javax.microedition.contactless.ndef.NDEFRecord;
//# import my.javax.microedition.contactless.ndef.NDEFRecordListener;
//# import my.javax.microedition.contactless.ndef.NDEFRecordType;
//# import my.javax.microedition.contactless.ndef.NDEFTagConnection;
//# import my.javax.microedition.contactless.ContactlessException;
//#else
import javax.microedition.contactless.DiscoveryManager;
import javax.microedition.contactless.TargetListener;
import javax.microedition.contactless.TargetProperties;
import javax.microedition.contactless.TargetType;
import javax.microedition.contactless.ndef.NDEFMessage;
import javax.microedition.contactless.ndef.NDEFRecord;
import javax.microedition.contactless.ndef.NDEFRecordListener;
import javax.microedition.contactless.ndef.NDEFRecordType;
import javax.microedition.contactless.ndef.NDEFTagConnection;
import javax.microedition.contactless.ContactlessException;
//#endif


/**
 * @author emarkki
 */
public class SampleAppAMIDlet extends MIDlet implements CommandListener, NDEFRecordListener, TargetListener {

    private static final NDEFRecordType SMARTPOSTER = 
            new NDEFRecordType(NDEFRecordType.NFC_FORUM_RTD, "urn:nfc:wkt:Sp");
    
    private boolean midletPaused = false;
    private boolean isWritingMode = false;
    private boolean isReadingMode = false;
    private NDEFMessage messageToWrite = null;
    private byte[] signatureBytes = null;
    private DiscoveryManager discoveryManager;
    
    private Cert[] certs;
    private CertificateVisualDesign visualDesign2;
    private X509Certificate[] trustedCerts;

//<editor-fold defaultstate="collapsed" desc=" Generated Fields ">//GEN-BEGIN:|fields|0|
private java.util.Hashtable __previousDisplayables = new java.util.Hashtable ();
private Command exitCommand;
private Command itemSimulateCommand;
private Command itemSimulateWriteCommand;
private Command exitCommand1;
private Command itemCommandRead;
private Command itemCommandWrite;
private Command backCommandReader;
private Command backCommand1;
private Command okCommandEdit;
private Command cancelCommandWriter;
private Command backCommandWriter;
private Command backCommand;
private Command okCommand;
private Command itemCommand;
private Command backCommand2;
private Command okCommand1;
private Command backCommand3;
private Command itemCommandShow;
private Form readerForm;
private StringItem stringItemReaderInstructions;
private List mainList;
private Form editSmartPosterForm;
private TextField textField;
private ChoiceGroup choiceGroupSignaturePresent;
private ChoiceGroup choiceGroupSignatureAlg;
private Spacer spacer;
private ChoiceGroup choiceGroupCertificateChain;
private ChoiceGroup choiceGroupCertificate;
private Form writerForm;
private StringItem stringItem1;
private Form editSignatureURI;
private TextField textFieldSignatureUri;
private Form editChainURI;
private TextField textFieldChainUri;
private List trustedCertificatesList;
//</editor-fold>//GEN-END:|fields|0|
    
//</editor-fold>
    
//</editor-fold>

    /**
     * The HelloMIDlet constructor.
     */
    public SampleAppAMIDlet() {
//        dumpChains();
    }
    
    private void createMessagePerformed() {
        try {
            getWriterForm().deleteAll();
            
            messageToWrite = createNewMessageToWrite();
            isWritingMode = true;
            
            getWriterForm().append("\nTouch the tag you want to write to...");

        } catch (DataLengthException ex) {
            ex.printStackTrace();
            getDisplay().setCurrent(new Alert("DataLengthException: ", ex.getMessage(), null, AlertType.ERROR), getWriterForm());
        } catch (SignatureException ex) {
            ex.printStackTrace();
            getDisplay().setCurrent(new Alert("SignException: ", ex.getMessage(), null, AlertType.ERROR), getWriterForm());
        } catch (IOException ex) {
            ex.printStackTrace();
            getDisplay().setCurrent(new Alert("IOException: ", ex.getMessage(), null, AlertType.ERROR), getWriterForm());
        } catch(WrongPrivateKeyAlgorithm ex) {
            getDisplay().setCurrent(new Alert("Signature algoritm", "Please choose a signature algorithm that matches the choosen certificate", null, AlertType.ERROR), getEditSmartPosterForm());
        }
    }

    private NDEFMessage createNewMessageToWrite() throws IOException, DataLengthException, SignatureException, WrongPrivateKeyAlgorithm {
        
        URIRecord uri1 = new URIRecord(new byte[]{(byte) 1}, getTextField().getString());

        NDEFMessage payload = new NDEFMessage(new NDEFRecord[]{uri1.toNDEFRecord()});

        Cert cert = getCerts()[choiceGroupCertificate.getSelectedIndex()];
        
        PrivateKey privKey = cert.getPrivateKey();
        
        CertificateBytes[] chain = cert.getChainBytes();
        
        CertificateBytes[] storeChain;
        URIRecord chainURI;
        
        if(choiceGroupCertificateChain.isSelected(0)) {
            storeChain = chain;
            chainURI = null;
        } else if(choiceGroupCertificateChain.isSelected(1)) {
            storeChain = new CertificateBytes[0];
            chainURI = new URIRecord(textFieldChainUri.getString());
            getWriterForm().append("Store the certificate chain for "+ cert.getTitle() +" on: " + chainURI.getURI() + "\n");
        } else {
            storeChain = new CertificateBytes[0];
            chainURI = cert.getBuiltInUri();
        }

        MessageToSign signMsg = new MessageToSign(payload);
               
        Signer signer;
        switch(choiceGroupSignatureAlg.getSelectedIndex()) {
            case 1:
                signer = new RSASSAPKCS1v15Signer(privKey, CertificateField.X509, storeChain, chainURI);
                break;
            case 2:
                signer = new DSASigner(privKey, CertificateField.X509, storeChain, chainURI);
                break;
            case 3:
                signer = new ECDSASigner(privKey, CertificateField.X509, storeChain, chainURI);
                break;
            case 0:
            default:
                signer = new RSASSAPSSSigner(privKey, CertificateField.X509, storeChain, chainURI);
        }
        
        signMsg.setSigner(new int[]{0}, signer);
        
        SignedMessage signed = signMsg.signMessage();
        
        Signature signature = signed.getRecordsSignature(0);
        signatureBytes = signature.getBytes();
        
        // Signature identified by URI?
        if(choiceGroupSignaturePresent.isSelected(1)) {
            signature.setURI(new URIRecord(textFieldSignatureUri.getString()));
        
            byte[] encoded = Base64.encode(signatureBytes);
            
            getWriterForm().append("Base64-encoded signature to put on " + textFieldSignatureUri.getString()+ ":\n" + new String(encoded) + "\n");
            
            System.out.println("Signature bytes:");
            Utils.dumpAsJavaByteArray(signatureBytes);
            System.out.println("Base64: " + new String(encoded));
        }
        
        NDEFMessage signedPayload = signed.toNDEFMessage();
        
        NDEFRecord smartPosterRecord = new NDEFRecord(SMARTPOSTER, new byte[0], signedPayload.toByteArray());

        NDEFMessage message = new NDEFMessage(new NDEFRecord[]{smartPosterRecord});
        Utils.dumpAsJavaByteArray(message.toByteArray());
        return message;
    }

    private String dump(NDEFMessage msg) {
        StringBuffer sb = new StringBuffer();
        
        sb.append("Msg[");
        NDEFRecord[] rs = msg.getRecords();
        for(int i = 0; i < rs.length; i++) {
            sb.append(dump(rs[i]));
            if(i != rs.length-1) {
                sb.append(",");
            }
        }
        sb.append("]");
        
        return sb.toString();
    }
    
    private String dump(NDEFRecord record) {
        StringBuffer sb = new StringBuffer();
        
        
        sb.append(record.getRecordType().getName());
        sb.append("(");
        // TODO nested payload
        if(record.getRecordType().equals(SMARTPOSTER)) {
            sb.append(dump(record.getNestedNDEFMessage(0)));
        }
        sb.append(")");
        
        return sb.toString();
    }

    private X509Certificate[] getTrustedCerts() {
        if(trustedCerts == null) {
            try {
                trustedCerts = new X509Certificate[] {
                    new X509Certificate(getClass().getResourceAsStream("files/markus2-pub.cer")),
                    new X509Certificate(getClass().getResourceAsStream("files/SwedenRootCA.cer")),
                    new X509Certificate(getClass().getResourceAsStream("files/NordicRootCA.cer")),
                    new X509Certificate(getClass().getResourceAsStream("files/swiss-root-pub.cer")),
                    new X509Certificate(getClass().getResourceAsStream("files/swiss-root-pub.cer")),
                    new X509Certificate(getClass().getResourceAsStream("files/a-root-ca.cer")),
                    new X509Certificate(getClass().getResourceAsStream("files/b-root-ca.cer")),
                    new X509Certificate(getClass().getResourceAsStream("files/c-root-ca.cer")),
                    new X509Certificate(getClass().getResourceAsStream("files/d-root-ca.cer")),
                };
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return trustedCerts;
    }

//<editor-fold defaultstate="collapsed" desc=" Generated Methods ">//GEN-BEGIN:|methods|0|
/**
 * Switches a display to previous displayable of the current displayable.
 * The <code>display</code> instance is obtain from the <code>getDisplay</code> method.
 */
private void switchToPreviousDisplayable () {
Displayable __currentDisplayable = getDisplay ().getCurrent ();
if (__currentDisplayable != null) {
Displayable __nextDisplayable = (Displayable) __previousDisplayables.get (__currentDisplayable);
if (__nextDisplayable != null) {
switchDisplayable (null, __nextDisplayable);
}
}
}
//</editor-fold>//GEN-END:|methods|0|

//<editor-fold defaultstate="collapsed" desc=" Generated Method: initialize ">//GEN-BEGIN:|0-initialize|0|0-preInitialize
/**
 * Initilizes the application.
 * It is called only once when the MIDlet is started. The method is called before the <code>startMIDlet</code> method.
 */
private void initialize () {//GEN-END:|0-initialize|0|0-preInitialize
        // write pre-initialize user code here
//GEN-LINE:|0-initialize|1|0-postInitialize
        // write post-initialize user code here
}//GEN-BEGIN:|0-initialize|2|
//</editor-fold>//GEN-END:|0-initialize|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Method: startMIDlet ">//GEN-BEGIN:|3-startMIDlet|0|3-preAction
/**
 * Performs an action assigned to the Mobile Device - MIDlet Started point.
 */
public void startMIDlet () {//GEN-END:|3-startMIDlet|0|3-preAction
        // write pre-action user code here
        discoveryManager = DiscoveryManager.getInstance();
        try {
            discoveryManager.addNDEFRecordListener(this, SMARTPOSTER);
            discoveryManager.addTargetListener(this, TargetType.NDEF_TAG);
        } catch (ContactlessException ex) {
            ex.printStackTrace();
        }
switchDisplayable (null, getMainList ());//GEN-LINE:|3-startMIDlet|1|3-postAction
        // write post-action user code here
}//GEN-BEGIN:|3-startMIDlet|2|
//</editor-fold>//GEN-END:|3-startMIDlet|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Method: resumeMIDlet ">//GEN-BEGIN:|4-resumeMIDlet|0|4-preAction
/**
 * Performs an action assigned to the Mobile Device - MIDlet Resumed point.
 */
public void resumeMIDlet () {//GEN-END:|4-resumeMIDlet|0|4-preAction
        // write pre-action user code here
//GEN-LINE:|4-resumeMIDlet|1|4-postAction
        // write post-action user code here
}//GEN-BEGIN:|4-resumeMIDlet|2|
//</editor-fold>//GEN-END:|4-resumeMIDlet|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Method: switchDisplayable ">//GEN-BEGIN:|5-switchDisplayable|0|5-preSwitch
/**
 * Switches a current displayable in a display. The <code>display</code> instance is taken from <code>getDisplay</code> method. This method is used by all actions in the design for switching displayable.
 * @param alert the Alert which is temporarily set to the display; if <code>null</code>, then <code>nextDisplayable</code> is set immediately
 * @param nextDisplayable the Displayable to be set
 */
public void switchDisplayable (Alert alert, Displayable nextDisplayable) {//GEN-END:|5-switchDisplayable|0|5-preSwitch
        // write pre-switch user code here
Display display = getDisplay ();//GEN-BEGIN:|5-switchDisplayable|1|5-postSwitch
Displayable __currentDisplayable = display.getCurrent ();
if (__currentDisplayable != null  &&  nextDisplayable != null) {
__previousDisplayables.put (nextDisplayable, __currentDisplayable);
}
if (alert == null) {
display.setCurrent (nextDisplayable);
} else {
display.setCurrent (alert, nextDisplayable);
}//GEN-END:|5-switchDisplayable|1|5-postSwitch
        // write post-switch user code here
}//GEN-BEGIN:|5-switchDisplayable|2|
//</editor-fold>//GEN-END:|5-switchDisplayable|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Method: commandAction for Displayables ">//GEN-BEGIN:|7-commandAction|0|7-preCommandAction
/**
 * Called by a system to indicated that a command has been invoked on a particular displayable.
 * @param command the Command that was invoked
 * @param displayable the Displayable where the command was invoked
 */
public void commandAction (Command command, Displayable displayable) {//GEN-END:|7-commandAction|0|7-preCommandAction
        // write pre-action user code here
if (displayable == editChainURI) {//GEN-BEGIN:|7-commandAction|1|111-preAction
if (command == backCommand2) {//GEN-END:|7-commandAction|1|111-preAction
                // write pre-action user code here
switchDisplayable (null, getEditSmartPosterForm ());//GEN-LINE:|7-commandAction|2|111-postAction
                // write post-action user code here
} else if (command == okCommand1) {//GEN-LINE:|7-commandAction|3|109-preAction
                // write pre-action user code here
isSignaturePresent ();//GEN-LINE:|7-commandAction|4|109-postAction
                // write post-action user code here
}//GEN-BEGIN:|7-commandAction|5|85-preAction
} else if (displayable == editSignatureURI) {
if (command == backCommand) {//GEN-END:|7-commandAction|5|85-preAction
                // write pre-action user code here
switchToPreviousDisplayable ();//GEN-LINE:|7-commandAction|6|85-postAction
                // write post-action user code here
} else if (command == okCommand) {//GEN-LINE:|7-commandAction|7|83-preAction
                // write pre-action user code here
switchDisplayable (null, getWriterForm ());//GEN-LINE:|7-commandAction|8|83-postAction
                // write post-action user code here
                createMessagePerformed();
}//GEN-BEGIN:|7-commandAction|9|49-preAction
} else if (displayable == editSmartPosterForm) {
if (command == backCommand1) {//GEN-END:|7-commandAction|9|49-preAction
                // write pre-action user code here
switchDisplayable (null, getMainList ());//GEN-LINE:|7-commandAction|10|49-postAction
                // write post-action user code here
} else if (command == okCommandEdit) {//GEN-LINE:|7-commandAction|11|53-preAction
                
isChainURIPresent ();//GEN-LINE:|7-commandAction|12|53-postAction
                // write post-action user code here
}//GEN-BEGIN:|7-commandAction|13|27-preAction
} else if (displayable == mainList) {
if (command == List.SELECT_COMMAND) {//GEN-END:|7-commandAction|13|27-preAction
                // write pre-action user code here
mainListAction ();//GEN-LINE:|7-commandAction|14|27-postAction
                // write post-action user code here
} else if (command == exitCommand1) {//GEN-LINE:|7-commandAction|15|30-preAction
                // write pre-action user code here
exitMIDlet ();//GEN-LINE:|7-commandAction|16|30-postAction
                // write post-action user code here
}//GEN-BEGIN:|7-commandAction|17|40-preAction
} else if (displayable == readerForm) {
if (command == backCommandReader) {//GEN-END:|7-commandAction|17|40-preAction
                // write pre-action user code here
                isReadingMode = false;
switchDisplayable (null, getMainList ());//GEN-LINE:|7-commandAction|18|40-postAction
                // write post-action user code here
                getReaderForm().deleteAll();
                getReaderForm().append(stringItemReaderInstructions);
}//GEN-BEGIN:|7-commandAction|19|131-preAction
} else if (displayable == trustedCertificatesList) {
if (command == List.SELECT_COMMAND) {//GEN-END:|7-commandAction|19|131-preAction
 // write pre-action user code here
trustedCertificatesListAction ();//GEN-LINE:|7-commandAction|20|131-postAction
 // write post-action user code here
} else if (command == backCommand3) {//GEN-LINE:|7-commandAction|21|137-preAction
 // write pre-action user code here
switchDisplayable (null, getMainList ());//GEN-LINE:|7-commandAction|22|137-postAction
 // write post-action user code here
}//GEN-BEGIN:|7-commandAction|23|59-preAction
} else if (displayable == writerForm) {
if (command == cancelCommandWriter) {//GEN-END:|7-commandAction|23|59-preAction
                // write pre-action user code here
switchDisplayable (null, getMainList ());//GEN-LINE:|7-commandAction|24|59-postAction
                // write post-action user code here
                isWritingMode = false;
}//GEN-BEGIN:|7-commandAction|25|7-postCommandAction
}//GEN-END:|7-commandAction|25|7-postCommandAction
        // write post-action user code here
}//GEN-BEGIN:|7-commandAction|26|
//</editor-fold>//GEN-END:|7-commandAction|26|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: exitCommand ">//GEN-BEGIN:|18-getter|0|18-preInit
/**
 * Returns an initiliazed instance of exitCommand component.
 * @return the initialized component instance
 */
public Command getExitCommand () {
if (exitCommand == null) {//GEN-END:|18-getter|0|18-preInit
            // write pre-init user code here
exitCommand = new Command ("Exit", Command.EXIT, 0);//GEN-LINE:|18-getter|1|18-postInit
            // write post-init user code here
}//GEN-BEGIN:|18-getter|2|
return exitCommand;
}
//</editor-fold>//GEN-END:|18-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: readerForm ">//GEN-BEGIN:|14-getter|0|14-preInit
/**
 * Returns an initiliazed instance of readerForm component.
 * @return the initialized component instance
 */
public Form getReaderForm () {
if (readerForm == null) {//GEN-END:|14-getter|0|14-preInit
            // write pre-init user code here
readerForm = new Form ("Read Smart Poster", new Item[] { getStringItemReaderInstructions () });//GEN-BEGIN:|14-getter|1|14-postInit
readerForm.addCommand (getBackCommandReader ());
readerForm.setCommandListener (this);//GEN-END:|14-getter|1|14-postInit
            // write post-init user code here
}//GEN-BEGIN:|14-getter|2|
return readerForm;
}
//</editor-fold>//GEN-END:|14-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: stringItemReaderInstructions ">//GEN-BEGIN:|16-getter|0|16-preInit
/**
 * Returns an initiliazed instance of stringItemReaderInstructions component.
 * @return the initialized component instance
 */
public StringItem getStringItemReaderInstructions () {
if (stringItemReaderInstructions == null) {//GEN-END:|16-getter|0|16-preInit
            // write pre-init user code here
stringItemReaderInstructions = new StringItem ("Instructions:", "Touch a smart poster to read from it...");//GEN-LINE:|16-getter|1|16-postInit
            // write post-init user code here
}//GEN-BEGIN:|16-getter|2|
return stringItemReaderInstructions;
}
//</editor-fold>//GEN-END:|16-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: itemSimulateCommand ">//GEN-BEGIN:|21-getter|0|21-preInit
/**
 * Returns an initiliazed instance of itemSimulateCommand component.
 * @return the initialized component instance
 */
public Command getItemSimulateCommand () {
if (itemSimulateCommand == null) {//GEN-END:|21-getter|0|21-preInit
            // write pre-init user code here
itemSimulateCommand = new Command ("Simulate read", Command.ITEM, 0);//GEN-LINE:|21-getter|1|21-postInit
            // write post-init user code here
}//GEN-BEGIN:|21-getter|2|
return itemSimulateCommand;
}
//</editor-fold>//GEN-END:|21-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: itemSimulateWriteCommand ">//GEN-BEGIN:|23-getter|0|23-preInit
/**
 * Returns an initiliazed instance of itemSimulateWriteCommand component.
 * @return the initialized component instance
 */
public Command getItemSimulateWriteCommand () {
if (itemSimulateWriteCommand == null) {//GEN-END:|23-getter|0|23-preInit
            // write pre-init user code here
itemSimulateWriteCommand = new Command ("Simulate write", Command.ITEM, 0);//GEN-LINE:|23-getter|1|23-postInit
            // write post-init user code here
}//GEN-BEGIN:|23-getter|2|
return itemSimulateWriteCommand;
}
//</editor-fold>//GEN-END:|23-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: exitCommand1 ">//GEN-BEGIN:|29-getter|0|29-preInit
/**
 * Returns an initiliazed instance of exitCommand1 component.
 * @return the initialized component instance
 */
public Command getExitCommand1 () {
if (exitCommand1 == null) {//GEN-END:|29-getter|0|29-preInit
            // write pre-init user code here
exitCommand1 = new Command ("Exit", Command.EXIT, 0);//GEN-LINE:|29-getter|1|29-postInit
            // write post-init user code here
}//GEN-BEGIN:|29-getter|2|
return exitCommand1;
}
//</editor-fold>//GEN-END:|29-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: itemCommandRead ">//GEN-BEGIN:|31-getter|0|31-preInit
/**
 * Returns an initiliazed instance of itemCommandRead component.
 * @return the initialized component instance
 */
public Command getItemCommandRead () {
if (itemCommandRead == null) {//GEN-END:|31-getter|0|31-preInit
            // write pre-init user code here
itemCommandRead = new Command ("Read", "Go into read mode", Command.ITEM, 0);//GEN-LINE:|31-getter|1|31-postInit
            // write post-init user code here
}//GEN-BEGIN:|31-getter|2|
return itemCommandRead;
}
//</editor-fold>//GEN-END:|31-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: itemCommandWrite ">//GEN-BEGIN:|33-getter|0|33-preInit
/**
 * Returns an initiliazed instance of itemCommandWrite component.
 * @return the initialized component instance
 */
public Command getItemCommandWrite () {
if (itemCommandWrite == null) {//GEN-END:|33-getter|0|33-preInit
            // write pre-init user code here
itemCommandWrite = new Command ("Write", "Go into write mode", Command.ITEM, 0);//GEN-LINE:|33-getter|1|33-postInit
            // write post-init user code here
}//GEN-BEGIN:|33-getter|2|
return itemCommandWrite;
}
//</editor-fold>//GEN-END:|33-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: mainList ">//GEN-BEGIN:|25-getter|0|25-preInit
/**
 * Returns an initiliazed instance of mainList component.
 * @return the initialized component instance
 */
public List getMainList () {
if (mainList == null) {//GEN-END:|25-getter|0|25-preInit
            // write pre-init user code here
mainList = new List ("Sample App A", Choice.IMPLICIT);//GEN-BEGIN:|25-getter|1|25-postInit
mainList.append ("Read a tag", null);
mainList.append ("Write new SmartPoster", null);
mainList.append ("Simulate read 1", null);
mainList.append ("Simulate read 2", null);
mainList.append ("Simulate read 3", null);
mainList.append ("Show trusted certificates", null);
mainList.addCommand (getExitCommand1 ());
mainList.setCommandListener (this);
mainList.setSelectedFlags (new boolean[] { false, false, false, false, false, false });//GEN-END:|25-getter|1|25-postInit
            // write post-init user code here
}//GEN-BEGIN:|25-getter|2|
return mainList;
}
//</editor-fold>//GEN-END:|25-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Method: mainListAction ">//GEN-BEGIN:|25-action|0|25-preAction
/**
 * Performs an action assigned to the selected list element in the mainList component.
 */
public void mainListAction () {//GEN-END:|25-action|0|25-preAction
        // enter pre-action user code here
String __selectedString = getMainList ().getString (getMainList ().getSelectedIndex ());//GEN-BEGIN:|25-action|1|35-preAction
if (__selectedString != null) {
if (__selectedString.equals ("Read a tag")) {//GEN-END:|25-action|1|35-preAction
                // write pre-action user code here
switchDisplayable (null, getReaderForm ());//GEN-LINE:|25-action|2|35-postAction
                // write post-action user code here
                isReadingMode = true;
} else if (__selectedString.equals ("Write new SmartPoster")) {//GEN-LINE:|25-action|3|36-preAction
                // write pre-action user code here
switchDisplayable (null, getEditSmartPosterForm ());//GEN-LINE:|25-action|4|36-postAction
                // write post-action user code here
} else if (__selectedString.equals ("Simulate read 1")) {//GEN-LINE:|25-action|5|46-preAction
                // write pre-action user code here
switchDisplayable (null, getReaderForm ());//GEN-LINE:|25-action|6|46-postAction
                // write post-action user code here
                isReadingMode = true;
                simulateRead1Performed();
} else if (__selectedString.equals ("Simulate read 2")) {//GEN-LINE:|25-action|7|93-preAction
                // write pre-action user code here
switchDisplayable (null, getReaderForm ());//GEN-LINE:|25-action|8|93-postAction
                // write post-action user code here
                isReadingMode = true;
                simulateRead2Performed();
} else if (__selectedString.equals ("Simulate read 3")) {//GEN-LINE:|25-action|9|95-preAction
                // write pre-action user code here
switchDisplayable (null, getReaderForm ());//GEN-LINE:|25-action|10|95-postAction
                // write post-action user code here
                isReadingMode = true;
                simulateRead3Performed();
} else if (__selectedString.equals ("Show trusted certificates")) {//GEN-LINE:|25-action|11|129-preAction
 // write pre-action user code here
switchDisplayable (null, getTrustedCertificatesList ());//GEN-LINE:|25-action|12|129-postAction
 // write post-action user code here
}//GEN-BEGIN:|25-action|13|25-postAction
}//GEN-END:|25-action|13|25-postAction
        // enter post-action user code here
}//GEN-BEGIN:|25-action|14|
//</editor-fold>//GEN-END:|25-action|14|


//<editor-fold defaultstate="collapsed" desc=" Generated Getter: backCommandReader ">//GEN-BEGIN:|39-getter|0|39-preInit
/**
 * Returns an initiliazed instance of backCommandReader component.
 * @return the initialized component instance
 */
public Command getBackCommandReader () {
if (backCommandReader == null) {//GEN-END:|39-getter|0|39-preInit
            // write pre-init user code here
backCommandReader = new Command ("Back", Command.BACK, 0);//GEN-LINE:|39-getter|1|39-postInit
            // write post-init user code here
}//GEN-BEGIN:|39-getter|2|
return backCommandReader;
}
//</editor-fold>//GEN-END:|39-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: editSmartPosterForm ">//GEN-BEGIN:|42-getter|0|42-preInit
/**
 * Returns an initiliazed instance of editSmartPosterForm component.
 * @return the initialized component instance
 */
public Form getEditSmartPosterForm () {
if (editSmartPosterForm == null) {//GEN-END:|42-getter|0|42-preInit
            // write pre-init user code here
editSmartPosterForm = new Form ("New Smart Poster", new Item[] { getTextField (), getSpacer (), getChoiceGroupCertificate (), getChoiceGroupCertificateChain (), getChoiceGroupSignatureAlg (), getChoiceGroupSignaturePresent () });//GEN-BEGIN:|42-getter|1|42-postInit
editSmartPosterForm.addCommand (getBackCommand1 ());
editSmartPosterForm.addCommand (getOkCommandEdit ());
editSmartPosterForm.setCommandListener (this);//GEN-END:|42-getter|1|42-postInit
            // write post-init user code here
}//GEN-BEGIN:|42-getter|2|
return editSmartPosterForm;
}
//</editor-fold>//GEN-END:|42-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: backCommand1 ">//GEN-BEGIN:|48-getter|0|48-preInit
/**
 * Returns an initiliazed instance of backCommand1 component.
 * @return the initialized component instance
 */
public Command getBackCommand1 () {
if (backCommand1 == null) {//GEN-END:|48-getter|0|48-preInit
            // write pre-init user code here
backCommand1 = new Command ("Back", Command.BACK, 0);//GEN-LINE:|48-getter|1|48-postInit
            // write post-init user code here
}//GEN-BEGIN:|48-getter|2|
return backCommand1;
}
//</editor-fold>//GEN-END:|48-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: okCommandEdit ">//GEN-BEGIN:|52-getter|0|52-preInit
/**
 * Returns an initiliazed instance of okCommandEdit component.
 * @return the initialized component instance
 */
public Command getOkCommandEdit () {
if (okCommandEdit == null) {//GEN-END:|52-getter|0|52-preInit
            // write pre-init user code here
okCommandEdit = new Command ("Ok", Command.OK, 0);//GEN-LINE:|52-getter|1|52-postInit
            // write post-init user code here
}//GEN-BEGIN:|52-getter|2|
return okCommandEdit;
}
//</editor-fold>//GEN-END:|52-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: textField ">//GEN-BEGIN:|51-getter|0|51-preInit
/**
 * Returns an initiliazed instance of textField component.
 * @return the initialized component instance
 */
public TextField getTextField () {
if (textField == null) {//GEN-END:|51-getter|0|51-preInit
            // write pre-init user code here
textField = new TextField ("URI:", "http://www.", 32, TextField.ANY);//GEN-LINE:|51-getter|1|51-postInit
            // write post-init user code here
}//GEN-BEGIN:|51-getter|2|
return textField;
}
//</editor-fold>//GEN-END:|51-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: backCommandWriter ">//GEN-BEGIN:|56-getter|0|56-preInit
/**
 * Returns an initiliazed instance of backCommandWriter component.
 * @return the initialized component instance
 */
public Command getBackCommandWriter () {
if (backCommandWriter == null) {//GEN-END:|56-getter|0|56-preInit
            // write pre-init user code here
backCommandWriter = new Command ("Back", Command.BACK, 0);//GEN-LINE:|56-getter|1|56-postInit
            // write post-init user code here
}//GEN-BEGIN:|56-getter|2|
return backCommandWriter;
}
//</editor-fold>//GEN-END:|56-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: writerForm ">//GEN-BEGIN:|54-getter|0|54-preInit
/**
 * Returns an initiliazed instance of writerForm component.
 * @return the initialized component instance
 */
public Form getWriterForm () {
if (writerForm == null) {//GEN-END:|54-getter|0|54-preInit
            // write pre-init user code here
writerForm = new Form ("Write to tag", new Item[] { getStringItem1 () });//GEN-BEGIN:|54-getter|1|54-postInit
writerForm.addCommand (getCancelCommandWriter ());
writerForm.setCommandListener (this);//GEN-END:|54-getter|1|54-postInit
            // write post-init user code here
}//GEN-BEGIN:|54-getter|2|
return writerForm;
}
//</editor-fold>//GEN-END:|54-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: stringItem1 ">//GEN-BEGIN:|55-getter|0|55-preInit
/**
 * Returns an initiliazed instance of stringItem1 component.
 * @return the initialized component instance
 */
public StringItem getStringItem1 () {
if (stringItem1 == null) {//GEN-END:|55-getter|0|55-preInit
            // write pre-init user code here
stringItem1 = new StringItem ("Instruction:", "Touch the tag you want to write to...");//GEN-LINE:|55-getter|1|55-postInit
            // write post-init user code here
}//GEN-BEGIN:|55-getter|2|
return stringItem1;
}
//</editor-fold>//GEN-END:|55-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: cancelCommandWriter ">//GEN-BEGIN:|58-getter|0|58-preInit
/**
 * Returns an initiliazed instance of cancelCommandWriter component.
 * @return the initialized component instance
 */
public Command getCancelCommandWriter () {
if (cancelCommandWriter == null) {//GEN-END:|58-getter|0|58-preInit
            // write pre-init user code here
cancelCommandWriter = new Command ("Cancel", Command.CANCEL, 0);//GEN-LINE:|58-getter|1|58-postInit
            // write post-init user code here
}//GEN-BEGIN:|58-getter|2|
return cancelCommandWriter;
}
//</editor-fold>//GEN-END:|58-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: choiceGroupSignatureAlg ">//GEN-BEGIN:|65-getter|0|65-preInit
/**
 * Returns an initiliazed instance of choiceGroupSignatureAlg component.
 * @return the initialized component instance
 */
public ChoiceGroup getChoiceGroupSignatureAlg () {
if (choiceGroupSignatureAlg == null) {//GEN-END:|65-getter|0|65-preInit
            // write pre-init user code here
choiceGroupSignatureAlg = new ChoiceGroup ("Signature algorithm:", Choice.EXCLUSIVE);//GEN-BEGIN:|65-getter|1|65-postInit
choiceGroupSignatureAlg.append ("RSASSA-PSS", null);
choiceGroupSignatureAlg.append ("RSASSA-PKCS1-v1_5 with SHA-1", null);
choiceGroupSignatureAlg.append ("DSA", null);
choiceGroupSignatureAlg.append ("ECDSA - P-192 with SHA-1", null);
choiceGroupSignatureAlg.setSelectedFlags (new boolean[] { true, false, false, false });
choiceGroupSignatureAlg.setFont (0, null);
choiceGroupSignatureAlg.setFont (1, null);
choiceGroupSignatureAlg.setFont (2, null);
choiceGroupSignatureAlg.setFont (3, null);//GEN-END:|65-getter|1|65-postInit
            // write post-init user code here
}//GEN-BEGIN:|65-getter|2|
return choiceGroupSignatureAlg;
}
//</editor-fold>//GEN-END:|65-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: spacer ">//GEN-BEGIN:|67-getter|0|67-preInit
/**
 * Returns an initiliazed instance of spacer component.
 * @return the initialized component instance
 */
public Spacer getSpacer () {
if (spacer == null) {//GEN-END:|67-getter|0|67-preInit
            // write pre-init user code here
spacer = new Spacer (16, 20);//GEN-BEGIN:|67-getter|1|67-postInit
spacer.setPreferredSize (-1, 22);//GEN-END:|67-getter|1|67-postInit
            // write post-init user code here
}//GEN-BEGIN:|67-getter|2|
return spacer;
}
//</editor-fold>//GEN-END:|67-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: choiceGroupSignaturePresent ">//GEN-BEGIN:|69-getter|0|69-preInit
/**
 * Returns an initiliazed instance of choiceGroupSignaturePresent component.
 * @return the initialized component instance
 */
public ChoiceGroup getChoiceGroupSignaturePresent () {
if (choiceGroupSignaturePresent == null) {//GEN-END:|69-getter|0|69-preInit
            // write pre-init user code here
choiceGroupSignaturePresent = new ChoiceGroup ("Signature present:", Choice.EXCLUSIVE);//GEN-BEGIN:|69-getter|1|69-postInit
choiceGroupSignaturePresent.append ("Yes", null);
choiceGroupSignaturePresent.append ("No, identify by URI", null);
choiceGroupSignaturePresent.setSelectedFlags (new boolean[] { true, false });
choiceGroupSignaturePresent.setFont (0, null);
choiceGroupSignaturePresent.setFont (1, null);//GEN-END:|69-getter|1|69-postInit
            // write post-init user code here
}//GEN-BEGIN:|69-getter|2|
return choiceGroupSignaturePresent;
}
//</editor-fold>//GEN-END:|69-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Method: isSignaturePresent ">//GEN-BEGIN:|74-if|0|74-preIf
/**
 * Performs an action assigned to the isSignaturePresent if-point.
 */
public void isSignaturePresent () {//GEN-END:|74-if|0|74-preIf
        // enter pre-if user code here
if (choiceGroupSignaturePresent.isSelected(0)) {//GEN-LINE:|74-if|1|75-preAction
            // write pre-action user code here
switchDisplayable (null, getWriterForm ());//GEN-LINE:|74-if|2|75-postAction
            // write post-action user code here
            createMessagePerformed();
} else {//GEN-LINE:|74-if|3|76-preAction
            // write pre-action user code here
switchDisplayable (null, getEditSignatureURI ());//GEN-LINE:|74-if|4|76-postAction
            // write post-action user code here
}//GEN-LINE:|74-if|5|74-postIf
        // enter post-if user code here
}//GEN-BEGIN:|74-if|6|
//</editor-fold>//GEN-END:|74-if|6|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: editSignatureURI ">//GEN-BEGIN:|73-getter|0|73-preInit
/**
 * Returns an initiliazed instance of editSignatureURI component.
 * @return the initialized component instance
 */
public Form getEditSignatureURI () {
if (editSignatureURI == null) {//GEN-END:|73-getter|0|73-preInit
            // write pre-init user code here
editSignatureURI = new Form ("URI for signature", new Item[] { getTextFieldSignatureUri () });//GEN-BEGIN:|73-getter|1|73-postInit
editSignatureURI.addCommand (getOkCommand ());
editSignatureURI.addCommand (getBackCommand ());
editSignatureURI.setCommandListener (this);//GEN-END:|73-getter|1|73-postInit
            // write post-init user code here
}//GEN-BEGIN:|73-getter|2|
return editSignatureURI;
}
//</editor-fold>//GEN-END:|73-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: okCommand ">//GEN-BEGIN:|82-getter|0|82-preInit
/**
 * Returns an initiliazed instance of okCommand component.
 * @return the initialized component instance
 */
public Command getOkCommand () {
if (okCommand == null) {//GEN-END:|82-getter|0|82-preInit
            // write pre-init user code here
okCommand = new Command ("Ok", Command.OK, 0);//GEN-LINE:|82-getter|1|82-postInit
            // write post-init user code here
}//GEN-BEGIN:|82-getter|2|
return okCommand;
}
//</editor-fold>//GEN-END:|82-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: backCommand ">//GEN-BEGIN:|84-getter|0|84-preInit
/**
 * Returns an initiliazed instance of backCommand component.
 * @return the initialized component instance
 */
public Command getBackCommand () {
if (backCommand == null) {//GEN-END:|84-getter|0|84-preInit
            // write pre-init user code here
backCommand = new Command ("Back", Command.BACK, 0);//GEN-LINE:|84-getter|1|84-postInit
            // write post-init user code here
}//GEN-BEGIN:|84-getter|2|
return backCommand;
}
//</editor-fold>//GEN-END:|84-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: textFieldSignatureUri ">//GEN-BEGIN:|81-getter|0|81-preInit
/**
 * Returns an initiliazed instance of textFieldSignatureUri component.
 * @return the initialized component instance
 */
public TextField getTextFieldSignatureUri () {
if (textFieldSignatureUri == null) {//GEN-END:|81-getter|0|81-preInit
            // write pre-init user code here
textFieldSignatureUri = new TextField ("Enter URI for signature:", null, 32, TextField.ANY);//GEN-LINE:|81-getter|1|81-postInit
            // write post-init user code here
}//GEN-BEGIN:|81-getter|2|
return textFieldSignatureUri;
}
//</editor-fold>//GEN-END:|81-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: itemCommand ">//GEN-BEGIN:|91-getter|0|91-preInit
/**
 * Returns an initiliazed instance of itemCommand component.
 * @return the initialized component instance
 */
public Command getItemCommand () {
if (itemCommand == null) {//GEN-END:|91-getter|0|91-preInit
            // write pre-init user code here
itemCommand = new Command ("Item", Command.ITEM, 0);//GEN-LINE:|91-getter|1|91-postInit
            // write post-init user code here
}//GEN-BEGIN:|91-getter|2|
return itemCommand;
}
//</editor-fold>//GEN-END:|91-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: choiceGroupCertificateChain ">//GEN-BEGIN:|97-getter|0|97-preInit
/**
 * Returns an initiliazed instance of choiceGroupCertificateChain component.
 * @return the initialized component instance
 */
public ChoiceGroup getChoiceGroupCertificateChain () {
if (choiceGroupCertificateChain == null) {//GEN-END:|97-getter|0|97-preInit
            // write pre-init user code here
choiceGroupCertificateChain = new ChoiceGroup ("Certificate chain present:", Choice.EXCLUSIVE);//GEN-BEGIN:|97-getter|1|97-postInit
choiceGroupCertificateChain.append ("Yes", null);
choiceGroupCertificateChain.append ("No, identify by URI", null);
choiceGroupCertificateChain.append ("No, use built-in URI", null);
choiceGroupCertificateChain.setFitPolicy (Choice.TEXT_WRAP_DEFAULT);
choiceGroupCertificateChain.setSelectedFlags (new boolean[] { true, false, false });
choiceGroupCertificateChain.setFont (0, null);
choiceGroupCertificateChain.setFont (1, null);
choiceGroupCertificateChain.setFont (2, null);//GEN-END:|97-getter|1|97-postInit
            // write post-init user code here
}//GEN-BEGIN:|97-getter|2|
return choiceGroupCertificateChain;
}
//</editor-fold>//GEN-END:|97-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Method: isChainURIPresent ">//GEN-BEGIN:|100-if|0|100-preIf
/**
 * Performs an action assigned to the isChainURIPresent if-point.
 */
public void isChainURIPresent () {//GEN-END:|100-if|0|100-preIf
        // enter pre-if user code here
if (choiceGroupCertificateChain.isSelected(1)) {//GEN-LINE:|100-if|1|101-preAction
            // write pre-action user code here
switchDisplayable (null, getEditChainURI ());//GEN-LINE:|100-if|2|101-postAction
            // write post-action user code here
} else {//GEN-LINE:|100-if|3|102-preAction
            // write pre-action user code here
isSignaturePresent ();//GEN-LINE:|100-if|4|102-postAction
            // write post-action user code here
}//GEN-LINE:|100-if|5|100-postIf
        // enter post-if user code here
}//GEN-BEGIN:|100-if|6|
//</editor-fold>//GEN-END:|100-if|6|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: okCommand1 ">//GEN-BEGIN:|108-getter|0|108-preInit
/**
 * Returns an initiliazed instance of okCommand1 component.
 * @return the initialized component instance
 */
public Command getOkCommand1 () {
if (okCommand1 == null) {//GEN-END:|108-getter|0|108-preInit
            // write pre-init user code here
okCommand1 = new Command ("Ok", Command.OK, 0);//GEN-LINE:|108-getter|1|108-postInit
            // write post-init user code here
}//GEN-BEGIN:|108-getter|2|
return okCommand1;
}
//</editor-fold>//GEN-END:|108-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: backCommand2 ">//GEN-BEGIN:|110-getter|0|110-preInit
/**
 * Returns an initiliazed instance of backCommand2 component.
 * @return the initialized component instance
 */
public Command getBackCommand2 () {
if (backCommand2 == null) {//GEN-END:|110-getter|0|110-preInit
            // write pre-init user code here
backCommand2 = new Command ("Back", Command.BACK, 0);//GEN-LINE:|110-getter|1|110-postInit
            // write post-init user code here
}//GEN-BEGIN:|110-getter|2|
return backCommand2;
}
//</editor-fold>//GEN-END:|110-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: editChainURI ">//GEN-BEGIN:|103-getter|0|103-preInit
/**
 * Returns an initiliazed instance of editChainURI component.
 * @return the initialized component instance
 */
public Form getEditChainURI () {
if (editChainURI == null) {//GEN-END:|103-getter|0|103-preInit
            // write pre-init user code here
editChainURI = new Form ("URI for certificate chain", new Item[] { getTextFieldChainUri () });//GEN-BEGIN:|103-getter|1|103-postInit
editChainURI.addCommand (getOkCommand1 ());
editChainURI.addCommand (getBackCommand2 ());
editChainURI.setCommandListener (this);//GEN-END:|103-getter|1|103-postInit
            // write post-init user code here
}//GEN-BEGIN:|103-getter|2|
return editChainURI;
}
//</editor-fold>//GEN-END:|103-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: textFieldChainUri ">//GEN-BEGIN:|117-getter|0|117-preInit
/**
 * Returns an initiliazed instance of textFieldChainUri component.
 * @return the initialized component instance
 */
public TextField getTextFieldChainUri () {
if (textFieldChainUri == null) {//GEN-END:|117-getter|0|117-preInit
            // write pre-init user code here
textFieldChainUri = new TextField ("Enter URI for certificate chain:", null, 32, TextField.ANY);//GEN-LINE:|117-getter|1|117-postInit
            // write post-init user code here
}//GEN-BEGIN:|117-getter|2|
return textFieldChainUri;
}
//</editor-fold>//GEN-END:|117-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: choiceGroupCertificate ">//GEN-BEGIN:|121-getter|0|121-preInit
/**
 * Returns an initiliazed instance of choiceGroupCertificate component.
 * @return the initialized component instance
 */
public ChoiceGroup getChoiceGroupCertificate () {
if (choiceGroupCertificate == null) {//GEN-END:|121-getter|0|121-preInit
            // write pre-init user code here
choiceGroupCertificate = new ChoiceGroup ("Certificate:", Choice.POPUP);//GEN-BEGIN:|121-getter|1|121-postInit
choiceGroupCertificate.setSelectedFlags (new boolean[] {  });//GEN-END:|121-getter|1|121-postInit
            // write post-init user code here
            for(int i = 0; i < getCerts().length; i++) {
                choiceGroupCertificate.append(getCerts()[i].getTitle(), null);
            }
}//GEN-BEGIN:|121-getter|2|
return choiceGroupCertificate;
}
//</editor-fold>//GEN-END:|121-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: itemCommandShow ">//GEN-BEGIN:|134-getter|0|134-preInit
/**
 * Returns an initiliazed instance of itemCommandShow component.
 * @return the initialized component instance
 */
public Command getItemCommandShow () {
if (itemCommandShow == null) {//GEN-END:|134-getter|0|134-preInit
 // write pre-init user code here
itemCommandShow = new Command ("Show", Command.ITEM, 0);//GEN-LINE:|134-getter|1|134-postInit
 // write post-init user code here
}//GEN-BEGIN:|134-getter|2|
return itemCommandShow;
}
//</editor-fold>//GEN-END:|134-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: backCommand3 ">//GEN-BEGIN:|136-getter|0|136-preInit
/**
 * Returns an initiliazed instance of backCommand3 component.
 * @return the initialized component instance
 */
public Command getBackCommand3 () {
if (backCommand3 == null) {//GEN-END:|136-getter|0|136-preInit
 // write pre-init user code here
backCommand3 = new Command ("Back", Command.BACK, 0);//GEN-LINE:|136-getter|1|136-postInit
 // write post-init user code here
}//GEN-BEGIN:|136-getter|2|
return backCommand3;
}
//</editor-fold>//GEN-END:|136-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Getter: trustedCertificatesList ">//GEN-BEGIN:|130-getter|0|130-preInit
/**
 * Returns an initiliazed instance of trustedCertificatesList component.
 * @return the initialized component instance
 */
public List getTrustedCertificatesList () {
if (trustedCertificatesList == null) {//GEN-END:|130-getter|0|130-preInit
 // write pre-init user code here
trustedCertificatesList = new List ("Trusted certificates", Choice.IMPLICIT);//GEN-BEGIN:|130-getter|1|130-postInit
trustedCertificatesList.addCommand (getBackCommand3 ());
trustedCertificatesList.setCommandListener (this);//GEN-END:|130-getter|1|130-postInit
 // write post-init user code here
X509Certificate[] certs = getTrustedCerts();
for(int i = 0; i < certs.length; i++) {
    trustedCertificatesList.append(certs[i].getStructure().getSubject().toString(), null);
}
}//GEN-BEGIN:|130-getter|2|
return trustedCertificatesList;
}
//</editor-fold>//GEN-END:|130-getter|2|

//<editor-fold defaultstate="collapsed" desc=" Generated Method: trustedCertificatesListAction ">//GEN-BEGIN:|130-action|0|130-preAction
/**
 * Performs an action assigned to the selected list element in the trustedCertificatesList component.
 */
public void trustedCertificatesListAction () {//GEN-END:|130-action|0|130-preAction
 // enter pre-action user code here
String __selectedString = getTrustedCertificatesList ().getString (getTrustedCertificatesList ().getSelectedIndex ());//GEN-LINE:|130-action|1|130-postAction
 // enter post-action user code here
int sel = getTrustedCertificatesList().getSelectedIndex();
if(sel < 0) {
    return;
}
X509CertificateChain chain = new X509CertificateChain(new X509Certificate[]{getTrustedCerts()[sel]});
getVisualDesign2().showCertificateChain(chain, trustedCertificatesList);
}//GEN-BEGIN:|130-action|2|
//</editor-fold>//GEN-END:|130-action|2|


private CertificateVisualDesign getVisualDesign2() {
    if (visualDesign2 == null) {
        visualDesign2 = new CertificateVisualDesign(this);
    }
    return visualDesign2;
}


    /**
     * Returns a display instance.
     * @return the display instance.
     */
    public Display getDisplay () {
        return Display.getDisplay(this);
    }

    /**
     * Exits MIDlet.
     */
    public void exitMIDlet() {
        switchDisplayable (null, null);
        destroyApp(true);
        notifyDestroyed();
    }

    /**
     * Called when MIDlet is started.
     * Checks whether the MIDlet have been already started and initialize/starts or resumes the MIDlet.
     */
    public void startApp() {
        if (midletPaused) {
            resumeMIDlet ();
        } else {
            initialize ();
            startMIDlet ();
        }
        midletPaused = false;
    }

    /**
     * Called when MIDlet is paused.
     */
    public void pauseApp() {
        midletPaused = true;
    }

    /**
     * Called to signal the MIDlet to terminate.
     * @param unconditional if true, then the MIDlet has to be unconditionally terminated and all resources has to be released.
     */
    public void destroyApp(boolean unconditional) {
        if (discoveryManager != null) {
            discoveryManager.removeNDEFRecordListener(this, SMARTPOSTER);
            discoveryManager.removeTargetListener(this, TargetType.NDEF_TAG);
            System.out.println("Removed listeners");
        }
    }

    private void simulateRead1Performed() {
        System.out.println("Simulating tag detected...");
        recordDetected(new NDEFMessage(SimulationData.MESSAGE1, 0));
    }
    
    private void simulateRead2Performed() {
        System.out.println("Simulating tag detected...");
        recordDetected(new NDEFMessage(SimulationData.MESSAGE2, 0));
    }
    
    private void simulateRead3Performed() {
        System.out.println("Simulating tag detected...");
        recordDetected(new NDEFMessage(SimulationData.MESSAGE3, 0));
    }
    
    public void recordDetected(NDEFMessage msg) { // TODO: the following should be done in a new thread
        
        System.out.println("recordDetected in mode read: " + isReadingMode);
        
        if(!isReadingMode) {
            return;
        }
        
        System.out.println(dump(msg));
        
        // TODO: the following should be done in a new thread
        NDEFRecord r = findFirstRecord(msg, SMARTPOSTER);

        if (r == null) {
            getReaderForm().append("No SmartPoster found.\n");
            return;
        }

        SmartPosterRecord sp = new SmartPosterRecord(r.getPayload());

        int interestingIndex = findFirstRecordIndex(sp.getRecords(), URIRecord.RECORD_TYPE);

        if (interestingIndex == -1) {
            getReaderForm().append("No URI in SmartPoster.\n");
            return;
        }

        Certificate[] trustedCerts = getTrustedCerts();

        MessageValidator validatorInfo = new MessageValidator(trustedCerts, new MySignatureWebFetcher(), new MyCertificateFetcher(getCerts()));

        SignedMessage results = validatorInfo.validate(r.getNestedNDEFMessage(0), new int[]{interestingIndex});

        Signature signature = results.getRecordsSignature(interestingIndex);

        URIRecord uri = new URIRecord(sp.getRecords()[interestingIndex].getPayload(), 0);

//            getReaderForm().append("\nURI: " + uri.getURI() + "\n");

        StringItem uriItem = new StringItem("URI: ", uri.getURI(), Item.HYPERLINK);
        // TODO: Add command action
        getReaderForm().append(uriItem);
        getReaderForm().append("\n");

        if(signature == null) {
            getReaderForm().append("Warning: Invalid signature");
        } else if(!signature.getStatus().isValid()) {
            getReaderForm().append("Warning: Invalid signature, " + signature.getStatus().getErrorMessage());
        } else {
            getReaderForm().append("Valid signature");
            if(signature.getStatus().getCertificateChain().getUserCertificate() instanceof X509Certificate) {
                getReaderForm().append("from " + Utils.getCommonName(((X509Certificate)signature.getStatus().getCertificateChain().getUserCertificate()).getStructure().getSubject()));
                StringItem item = new StringItem("Show: ", "Certificate", Item.BUTTON);

                final X509CertificateChain chain = (X509CertificateChain) signature.getStatus().getCertificateChain();

                item.setDefaultCommand(new Command("Show", Command.ITEM, 1));
                item.setItemCommandListener(new ItemCommandListener() {

                    public void commandAction(Command arg0, Item arg1) {
                        getVisualDesign2().showCertificateChain(chain, readerForm);
                    }
                });
                getReaderForm().append(item);
            }
        }        
    }
    
    private NDEFRecord findFirstRecord(NDEFMessage msg, NDEFRecordType type) {
        return findFirstRecord(msg.getRecords(), type);
    }
    
    private NDEFRecord findFirstRecord(NDEFRecord[] records, NDEFRecordType type) {
        
        int i = findFirstRecordIndex(records, type);
        
        if(i == -1) {
            return null;
        }
        
        return records[i];
    }
    
    private int findFirstRecordIndex(NDEFRecord[] records, NDEFRecordType type) {
        
        for(int i = 0; i < records.length; i++) {
            if(type.equals(records[i].getRecordType())) {
                return i;
            }
        }
        
        return -1;
    }

    public void targetDetected(TargetProperties[] props) {
        System.out.println("targetDetected, writing mode: " + isWritingMode + ", msgToWrite: " + messageToWrite);
        
        NDEFTagConnection conn = null;

        try {
        
            if(!isWritingMode) {
                return;
            }

            getWriterForm().append("Target detected\n");

            if(messageToWrite == null) {
                getWriterForm().append("No message to write!\n");
                return;
            }

            if(props == null || props.length == 0) {
                getWriterForm().append("No TargetProperties found!\n");
                return;
            }
        
            conn = getNDEFTAGConnection(props);
        
            if(conn == null) {
                getWriterForm().append("No supported TargetProperies found!");
                return;
            }
            
            getWriterForm().append("Starting to write...");
            conn.writeNDEF(messageToWrite);
            getWriterForm().append("done.\n");
            
        } catch (ContactlessException ex) {
            ex.printStackTrace();
            getWriterForm().append("ContactlessException: " + ex.getMessage());
        } catch (IOException ex) {
            ex.printStackTrace();
            getWriterForm().append("IOException: " + ex.getMessage());
        } finally {
            if(conn != null) {
                try {
                    conn.close();
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
    
    public NDEFTagConnection getNDEFTAGConnection(TargetProperties[] tProp) throws IOException {
        for (int j = 0; j < tProp.length; j++) {
            Class[] connections = tProp[j].getConnectionNames();
            if (connections != null) {
                for (int i = 0; i < connections.length; i++) {
                    if (connections[i].getName().equals(
                            "javax.microedition.contactless.ndef.NDEFTagConnection")) {
                        return (NDEFTagConnection) Connector.open(tProp[0].getUrl(connections[i]));
                    }
                }
            }
        }
        return null;
    }

    private Cert[] getCerts() {
        if(certs == null) {
            try {
                certs = new Cert[] {
                    
                    new Cert("A User 1 (RSA) (2)", new URIRecord("sampleappa:auser1"), new PrivateKey(getClass().getResourceAsStream("files/a-user1-private.der")), Cert.KEY_RSA, new X509Certificate[]{new X509Certificate(getClass().getResourceAsStream("files/a-user1.cer"))}),
                    new Cert("A User 2 (RSA) (2)", new URIRecord("sampleappa:auser2"), new PrivateKey(getClass().getResourceAsStream("files/a-user2-private.der")), Cert.KEY_RSA, new X509Certificate[]{new X509Certificate(getClass().getResourceAsStream("files/a-user2.cer"))}),
                    new Cert("A User 3 (DSA) (2)", new URIRecord("sampleappa:auser3"), new PrivateKey(getClass().getResourceAsStream("files/a-user3-private.der")), Cert.KEY_DSA, new X509Certificate[]{new X509Certificate(getClass().getResourceAsStream("files/a-user3.cer"))}),
                    new Cert("A User 4 (DSA) (2)", new URIRecord("sampleappa:auser4"), new PrivateKey(getClass().getResourceAsStream("files/a-user4-private.der")), Cert.KEY_DSA, new X509Certificate[]{new X509Certificate(getClass().getResourceAsStream("files/a-user4.cer"))}),
                    new Cert("B User 1 (RSA) (2)", new URIRecord("sampleappa:buser1"), new PrivateKey(getClass().getResourceAsStream("files/b-user1-private.der")), Cert.KEY_RSA, new X509Certificate[]{new X509Certificate(getClass().getResourceAsStream("files/b-user1.cer"))}),
                    new Cert("B User 2 (RSA) (2)", new URIRecord("sampleappa:buser2"), new PrivateKey(getClass().getResourceAsStream("files/b-user2-private.der")), Cert.KEY_RSA, new X509Certificate[]{new X509Certificate(getClass().getResourceAsStream("files/b-user2.cer"))}),
                    new Cert("C User 1 (ECDSA) (2)", new URIRecord("sampleappa:cuser1"), new PrivateKey(getClass().getResourceAsStream("files/c-user1-private.der")), Cert.KEY_ECDSA, new X509Certificate[]{new X509Certificate(getClass().getResourceAsStream("files/c-user1.cer"))}),
                    new Cert("D User 1 (DSA) (2)", new URIRecord("sampleappa:duser1"), new PrivateKey(getClass().getResourceAsStream("files/d-user1-private.der")), Cert.KEY_DSA, new X509Certificate[]{new X509Certificate(getClass().getResourceAsStream("files/d-user1.cer"))}),
                    new Cert("D User 2 (DSA) (2)", new URIRecord("sampleappa:duser2"), new PrivateKey(getClass().getResourceAsStream("files/d-user2-private.der")), Cert.KEY_DSA, new X509Certificate[]{new X509Certificate(getClass().getResourceAsStream("files/d-user2.cer"))}),
                    //new Cert("D User 3 (DSA) (2)", new URIRecord("sampleappa:duser3"), new PrivateKey(getClass().getResourceAsStream("files/d-user3-private.der")), Cert.KEY_DSA, new X509Certificate[]{new X509Certificate(getClass().getResourceAsStream("files/d-user3.cer"))}),
                    new Cert("D User ?4? (DSA) (2)", new URIRecord("sampleappa:duser4_"), new PrivateKey(getClass().getResourceAsStream("files/d-user4b-private.der")), Cert.KEY_DSA, new X509Certificate[]{new X509Certificate(getClass().getResourceAsStream("files/d-user4b.cer"))}),
                    new Cert("D User 4 (DSA) (2)", new URIRecord("sampleappa:duser4"), new PrivateKey(getClass().getResourceAsStream("files/d-user4-private.der")), Cert.KEY_ECDSA, new X509Certificate[]{new X509Certificate(getClass().getResourceAsStream("files/d-user4.cer"))}),

                    new Cert("Min User 1 (RSA) (2)", new URIRecord("sampleappa:minuser1"), new PrivateKey(getClass().getResourceAsStream("files/minuser1-private.der")), Cert.KEY_RSA, new X509Certificate[]{new X509Certificate(getClass().getResourceAsStream("files/minuser1-signed.cer"))}),
                    new Cert("Min User 2 (DSA) (2)", new URIRecord("sampleappa:minuser2"), new PrivateKey(getClass().getResourceAsStream("files/minuser2-private.der")), Cert.KEY_DSA, new X509Certificate[]{new X509Certificate(getClass().getResourceAsStream("files/minuser2-signed.cer"))}),
                    new Cert("Min User 3 (ECDSA) (2)", new URIRecord("sampleappa:minuser3"), new PrivateKey(getClass().getResourceAsStream("files/minuser3-private.der")), Cert.KEY_ECDSA, new X509Certificate[]{new X509Certificate(getClass().getResourceAsStream("files/minuser3-signed.cer"))}),
                    
                    new Cert("Nordic Root (RSA) (1)", new URIRecord("sampleappa:certificate-nordic"), new PrivateKey(getClass().getResourceAsStream("files/nordic-root-private2.der")), Cert.KEY_RSA, new X509Certificate[]{}),
                    new Cert("Scandinavia Root (DSA) (1)", new URIRecord("sampleappa:certificate-scand"), new PrivateKey(getClass().getResourceAsStream("files/scandinavia-root-private2.der")), Cert.KEY_DSA, new X509Certificate[]{}),
                    new Cert("Swiss Root (ECDSA) (1)", new URIRecord("sampleappa:certificate-swiss"), new PrivateKey(getClass().getResourceAsStream("files/swiss-root-private2.der")), Cert.KEY_ECDSA, new X509Certificate[]{}),
                    
                    new Cert("Anders B (RSA) (2)", new URIRecord("sampleappa:certificate1"), new PrivateKey(getClass().getResourceAsStream("files/AndersB-priv.der")), Cert.KEY_RSA, new X509Certificate[]{new X509Certificate(getClass().getResourceAsStream("files/AndersB-pub.cer"))}),
                    
                    new Cert("Lars L (RSA) (4)", new URIRecord("sampleappa:certificate2"), new PrivateKey(getClass().getResourceAsStream("files/LarsLarsson-priv.der")), Cert.KEY_RSA, new X509Certificate[]{
                        new X509Certificate(getClass().getResourceAsStream("files/LarsLarsson.cer")),
                        new X509Certificate(getClass().getResourceAsStream("files/BusCompanyCA.cer")),
                        new X509Certificate(getClass().getResourceAsStream("files/StockholmslanCA.cer")),
                        new X509Certificate(getClass().getResourceAsStream("files/SodermanlandCA.cer"))
                    }),
                    
                    new Cert("Mora-Nisse (ECDSA) (3)", new URIRecord("sampleappa:certificate3"), new PrivateKey(getClass().getResourceAsStream("files/MoraNisse-priv.der")), Cert.KEY_ECDSA, new X509Certificate[]{
                        new X509Certificate(getClass().getResourceAsStream("files/MoraNisse.cer")),
                        new X509Certificate(getClass().getResourceAsStream("files/DalarnaCA.cer")),
                        new X509Certificate(getClass().getResourceAsStream("files/NordicRootCA.cer"))
                    }),
                    
                    new Cert("Lars-Nils (DSA) (4)", new URIRecord("sampleappa:certificate4"), new PrivateKey(getClass().getResourceAsStream("files/LarsNils-priv.der")), Cert.KEY_DSA, new X509Certificate[]{
                        new X509Certificate(getClass().getResourceAsStream("files/LarsNils.cer")),
                        new X509Certificate(getClass().getResourceAsStream("files/DalatrafikCA.cer")),
                        new X509Certificate(getClass().getResourceAsStream("files/DalarnaCA.cer")),
                        new X509Certificate(getClass().getResourceAsStream("files/NordicRootCA.cer"))
                    }),
                };
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return certs;
    }

    void dumpChains() {
        for(int j = 0; j < getCerts().length; j++) {
            System.out.println("-- Begin chain " + j);
            CertificateBytes[] bytes = getCerts()[j].getChainBytes();
            try {
                for(int i = 0; i < bytes.length; i++) {

                        Base64.encode(bytes[i].getBytes(), System.out);
                        System.out.println();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            System.out.println("-- End chain " + j);
        }
    }
    
}
